<?php
/**
 * Database class
 * Handles database interaction.
 * @author Alberto Miranda
 */
class Database{
	//parametros mysql
	public $host        = "";
	public $dsn         = "DSN=SADYM-desarrollo;Initial Catalog=Sadym;Persist Security Info=True;User ID=Sadym_2;Password=sadym";
	public $user        = "";
	public $password    = "";
	public $database    = "";
	public $conn        = ""; //internal connection reference
	public $serverType; //["mssql"|"mysql"|"odbc"]
	
	
	

	/**
     * Constructor
     * @author Alberto Miranda
     * @param string $enviroment [development|production]
     */
	public function __construct(){
        //set class config
        $this->host             = 'localhost';
        $this->user             = $CONFIG['dbuser'];
        $this->password         = $CONFIG['dbpass'];
        $this->database         = $CONFIG['dbname'];
        $this->serverType       = $CONFIG['type'];
	}

	//---------------------------------------------------------------------

    /**
     * Establishes database connection
     * @author Alberto Miranda
     */
	private function connect(){
		switch($this->serverType){
			case "mysql":
				//conecto con el server
				$this->conn = @mysql_connect($this->host,$this->user,$this->password);
				
				//selecciono la BBDD
				@mysql_select_db($this->database,$this->conn);
				break;
			
			case "mssql":
				//conecto con el server
				$this->conn = @mssql_connect($this->host,$this->user,$this->password);
                				
				//selecciono la BBDD
				@mssql_select_db($this->database,$this->conn);
				break;
				
			case "odbc":
				//conecto con el server
				$this->conn = @odbc_connect($this->dsn,$this->user,$this->password) or die("No se pudo conectar via ODBC.");				
				break;
		}
	}

    /**
     * Disconnects from database
     * @author Alberto Miranda
     */
	private function disconnect(){
		//desconecto de MySQL	
		switch($this->serverType){		
			case "mysql":
					@mysql_close($this->conn);
					break;
				
				case "mssql":
					@mssql_close($this->conn);
					break;
					
				case "odbc":
					@odbc_close($this->conn);				
					break;
		}
	}
	//---------------------------------------------------------------------
	
	
	
	
	
	
	
	//---------------------------------------------------------------------
	//Queries start
	//---------------------------------------------------------------------
        /**
         * Executes an sql query and returns all result rows, if available
         * in a bidimensional array.
         *
         * @author Alberto Miranda
         * @param string $query
         * @param boolean $count
         * @param boolean $test
         * @param int $porcentaje
         * @return array
         */
		public function query($query, $count='', $test='', $porcentaje=''){
			//creo una nueva conexion al server
			$this->connect();
			
			//agrego paginacion si fue seteada
			if(isset($_REQUEST['minLimit']) && isset($_REQUEST['limit']) && empty($count)){
				$query.=" LIMIT " . $_REQUEST['minLimit'] . ", " . $_REQUEST['limit'];
			}

            /*
            echo "<br />\n***********************<br />\n";
            echo "+ CONNECTION RESOURCE: {$this->conn} (pre)";
            echo "<br />\n***********************<br />\n";
             * 
             */

			//ejecuto el query
			switch($this->serverType){
				case "mysql":
					$result=@mysql_query($query, $this->conn);
					
					//cierro la conexion al server
					mysql_close($this->conn);
					break;
					
				case "mssql":
					$result=@mssql_query($query, $this->conn);

					//cierro la conexion al server
					mssql_close($this->conn);
					break;
					
				case "odbc":
					$result=@odbc_exec($this->conn, $query);
					break;
			}

            /*
            echo "<br />\n***********************<br />\n";
            echo "+ CONNECTION RESOURCE: {$this->conn} (post)";
            echo "<br />\n***********************<br />\n";
             * 
             */


            //------------------------------------------------------------------
            //check for errors
            if($result===false){
                $errorDescription = mssql_get_last_message();
                $result = $this->composeResult("err", $errorDescription, $query);
                return $result;
            }
            //------------------------------------------------------------------

			
			//si se seteo $count significa que se desea obtener solo
			//la cantidad de registros afectados
			if(!empty($count)){
				switch($this->serverType){
					case "mysql":
						$resultados=mysql_num_rows($result);		
						break;
						
					case "mssql":
						$resultados=mssql_num_rows($result);
						break;
						
					case "odbc":
						$resultados=odbc_num_rows($result);
						break;
				}
				
				return $resultados;	
			} else {
				$queryResult_array=array();
                //when executing updates and inserts the result is a boolean
                //true and not a fetchable result
				if(!empty($result) && $result!==true){
					//recorro el recordset con los resultados	
					//salto de registro a registro
					$row=0;
										
					while($rs = $this->fetch($result)){
						//paso el registro actual a un array
						//para cada campo...
						foreach($rs as $field_name => $value){
							if(!empty($porcentaje)){
								//guardo el porcentaje indicado del total
								$queryResult_array[$row][$field_name]=$value*$porcentaje/100;
							} else {
								$queryResult_array[$row][$field_name]=$value;
							}
						}
						//incremento la posici�n en el array
						$row++;
					}//end while
				}
				
				
				if(!empty($test)){
					print_r($queryResult_array);
				} else {
					return $queryResult_array;
				}
				
			}//end if count
		}//end function query
		
		//-------------------------------------------------------------
		
		/**
		 * Fetch data.
		 *
         * @author Alberto Miranda
		 * @param resultset $result
		 * @return recordset $rs
		 */
		function fetch($result){
			switch($this->serverType){
				case "mysql":
					$rs = mysql_fetch_array($result,MYSQL_ASSOC);		
					break;
					
				case "mssql":
					$rs = mssql_fetch_array($result, MSSQL_ASSOC);
					break;
					
				case "odbc":
					$rs = odbc_fetch_array($result);
					break;
			}
			
			return $rs;
		}
		
		
		//-------------------------------------------------------------
		//-------------------------------------------------------------
	
		
		/**
         * Queries $table for the fields $fields_array and returns an array
         * of results with all matching records with $where, ordered by $order.
         *
		 * @author Alberto Miranda
         * @return BiArray
		 * @param String $table
		 * @param Array $fields_array
		 * @param String $where
		 * @param String $order
		 * @param * $count
		 * @param * $test
         * @return array
		*/
		public function get_data($table, $fields_array='*', $where='', $order='', $count='', $debug=''){
		
			//--[ SELECT ]-----------------------------------
			//genero la porci�n de la consulta SQL que indica
			//los campos a mostrar - SELECT
			if(is_array($fields_array)){
				$fields="";
				foreach ($fields_array as $campo => $alias){
					//agrego la coma y espacio al final
					if($fields!=""){
						$fields.=", ";		
					}
					
					$fields.="$campo as '$alias'";
				}
			} else {
				$fields=$fields_array;	
			}
						
			//--[ WHERE ]------------------------------------
			//genero la porci�n SQL de la cl�usula WHERE
			if(!empty($where)){
				//agrego la instrucci�n "where"
				$where="where " . $where;	
			}
			
			//-----------------------------------------------
			
			//--[ ORDER ]------------------------------------
			//genero la porci�n SQL de la cl�usula ORDER
			if(!empty($order)){
				//agrego la instrucci�n "order"
				$order="ORDER BY " . $order;	
			}
			
			//-----------------------------------------------
			
			
			
				
			
			$query="
				select $fields from $table $where $order";
			
			
			
			
					
			//-----------------------------------------------
			
			
			
			if($debug){
				//test
				echo "
				<!-- 
					QUERY -----------------------------------------
					$query
					-----------------------------------------
				-->";
				exit;
			}
			
			
						
			
			//ejecuto el query
			//y devuelvo el array de contactos
			return $this->query($query, $count, $debug);
			
		}
		
		//---------------------------------------------------------------------
		
		/**
         * Returns an array with the fields for $table.
         *
         * @author Alberto Miranda
		 * @param String $table
		 * @param * $count
		 * @param * $test
         * @return array
		*/
		public function get_fields($table, $count='', $debug=false){

			
				
			$query="SHOW COLUMNS FROM $table";
			
			
					
			//test
			if(!empty($test)){
				echo "QUERY: \n";
				echo $query . "\n\n";
			}
				
			//ejecuto el query
			//y devuelvo el array de contactos
			return $this->query($query, $count, $test);
			
		}
		
		//---------------------------------------------------------------------
		

		/**
		*   Generic insert.
			Toma los datos enviados en el array $data_array, 
			generalmente un subarray de $_POST, para generar el query,
			esperando que todos los campos a insertar se env�en en el
			formulario.
			
			Si se env�a un grupo de CheckBoxes se toman todos sus valores
			y se guardan separados por coma en el nombre de campo indicado en:
			chk_[nombre_campo]_[valor]
			
			[nombre_campo] es el nombre del campo en la Tabla de la dB.
			[valor] es el valor del elemento actual.
		* 
		* @return String id
		* @param String $table - Nombre de la tabla en donde se har� el insert
		* @param String $table_id - Nombre del campo ID de la tabla
		* @param * $test
		* @desc 
		*/
		public function insert_record($table, $data_array, $table_id="id", $debug=false){
		
			//recibo todas las vars que llegan por POST, las cuales
			//se deben enviar respetando los nombres de los campos en la dB
			$field_list="";
			$field_values="";
			foreach ($data_array as $key => $value){
				//omito la variable "Submit" asociada al bot�n de env�o
				if($key!="Submit" && $key!="submit" && $key!="conf_page" && $key!="id"){	
					
					$iniChars=substr($key, 0, 3);
					if($iniChars=='chk'){
						$chkName_array=explode("_", $key);
						$chk_field=$chkName_array[1];
						
						if(!empty($chk_array[$chk_field])){
							$chk_array[$chk_field].="," . $value;
						} else {
							$chk_array[$chk_field]=$value;
						}
					} else {
								
						//agrego separador
						if(!empty($field_list)){
							$field_list.=", ";	
							$field_values.=", ";
						}
						
						$field_list.="`$key`";
						$field_values.="'$value'";
					}
				}
			}
			
			//si hubo chks los agrego al query
			if(!empty($chk_array)){
				foreach ($chk_array as $field_name => $field_value){
					$field_list.=", `$field_name`";
					$field_values.=", '$field_value'";	
				}
			}
			
			//-------------------------------------------------------------
			
			
			
			
			$query="INSERT INTO `$table` ($table_id, $field_list) VALUES (NULL, $field_values)";
						

					
			
			if($debug){
				//test
				echo "
				<!-- 
					QUERY -----------------------------------------
					$query
					-----------------------------------------
				-->";
				exit;
			}
			
		
			
				
			//conecto a la dB usando el m�todo heredado de la clase Database
			$this->connect();
			
			/*
				Si el insert no pudo realizarse no se debe continuar con el
				proceso, ya que se necesita el id generado por este insert.
				Si no se considera la falla del insert, mysql_insert_id
				obtendr� el valor del �ltimo insert o update que funcion�,
				guardando datos inv�lidos en el siguiente insert.
			*/
			mysql_query($query, $this->conn) or die(mysql_error());
			$record_id=mysql_insert_id();//obtengo el id del cliente reci�n insertado
					
			
			//termin� de operar con la dB, desconecto utilizando 
			//el m�todo heredado de la clase Database
			$this->disconnect();
			
			
			//devuelvo el ID del registro insertado
			return $record_id;
			
		}
		
		//---------------------------------------------------------------------
		

		public function update_record($table, $table_id, $id, $table_pass='pass', $debug=false){
		/*
			Realiza el update del registro en la base de datos.
			Toma los datos para el alta de POST.
			
			Recibe como par�metro el nombre de la Tabla en donde se
			encuentra el registro.
		*/	
		
		
			//recibo todas las vars que llegan por POST, las cuales
			//se deben enviar respetando los nombres de los campos en la dB
			$field_list="";
			$field_values="";
			foreach ($_POST as $key => $value){
				//omito la variable "Submit" asociada al bot�n de env�o
				if($key!="Submit" && $key!="submit" && $key!="conf_page" && $key!="id"){	
					
					$iniChars=substr($key, 0, 3);
					if($iniChars=='chk'){
						$chkName_array=explode("_", $key);
						$chk_field=$chkName_array[1];
						
						if(!empty($chk_array[$chk_field])){
							$chk_array[$chk_field].="," . $value;
						} else {
							$chk_array[$chk_field]=$value;
						}
					} else {
							
						if($key=="$table_pass"){
							if(!empty($value)){
								//Non empty pass
								$value=md5($value); //encripto el pass
								
								//agrego separador
								if(!empty($field_values)){
									$field_values.=", ";
								}
								
								$field_values.="`$key`='$value'";
							}
						} else {
							//normal field
							//agrego separador
							if(!empty($field_values)){
								$field_values.=", ";
							}
							
							$field_values.="`$key`='$value'";	
							}	
					}
				}
			}
			
			//si hubo chks los agrego al query
			if(!empty($chk_array)){
				foreach ($chk_array as $field_name => $field_value){
					$field_values.=", `$field_name`='$field_value'";	
				}
			}
			
			//-------------------------------------------------------------
			
			
			
			

			
			
			$query="UPDATE `$table` SET $field_values WHERE `$table_id`=$id";
						
			
			
			
			
			if($debug){
				//test
				echo "
				<!-- 
					QUERY -----------------------------------------
					$query
					-----------------------------------------
				-->";
				exit;
			}
			
		
			
				
			//conecto a la dB usando el m�todo heredado de la clase Database
			$this->connect();

			//realizo el query		
			mysql_query($query, $this->conn) or die(mysql_error());
			
			//termin� de operar con la dB, desconecto utilizando 
			//el m�todo heredado de la clase Database
			$this->disconnect();			
		}
		
		//---------------------------------------------------------------------
		
		/**
		 * Elimino el registro con el ID suministrado en
		 * la tabla suministrada.
		 *
		 * @param String $table
		 * @param String $id
		 */
		public function delete_record($table, $id, $idField="id"){
			//query
			$query="DELETE FROM $table WHERE $idField=$id";
			
			//conecto a la dB usando el m�todo heredado de la clase Database
			$this->connect();

			//realizo el query		
			mysql_query($query, $this->conn) or die(mysql_error());
			
			//termin� de operar con la dB, desconecto utilizando 
			//el m�todo heredado de la clase Database
			$this->disconnect();
		}
		
		//---------------------------------------------------------------------
		
				
		/**
		* @return Array Resultados de la b�squeda
		* @param String $table Nombre de la Tabla en que se desea buscar
		* @param Any $test Si se setea se ejecuta en modo Test, s�lo mostrando el Query SQL
		* @desc 
			Realiza la b�squeda de registros en la tabla indicada.
			Todas las variables pasadas por POST desde el form de b�squeda
			son utilizadas para generar el contenido de la cl�usula WHERE.
			Cada campo de dicho form debe corresponder con los nombres
			de los campos en la Tabla de la dB.
		*/
		public function find_record($table, $fields_array='*', $where_array='', $test=''){
			
			foreach ($_POST as $key => $value) {
				$$key=$value;
			}
			
			$where="";
			if(is_array($where_array)){
				foreach ($where_array as $field_name => $field_value){
					if(!empty($where)){
						$where.=" and ";	
					}
					
					$where.="$field_name='$field_value'";
				}	
			} else {
				$where=$where_array;	
			}
			//-------------------------------------------------------------
			
			//genero la porci�n de la consulta SQL que indica
			//los campos a mostrar
			if(is_array($fields_array)){
				$fields="";
				foreach ($fields_array as $campo => $alias){
					//agrego la coma y espacio al final
					if($fields!=""){
						$fields.=", ";		
					}
					
					$fields.="$campo as '$alias'";
				}
			} else {
				$fields=$fields_array;	
			}
			
			//-------------------------------------------------------------

			
			
			
			
			
			$query="SELECT $fields FROM $table WHERE $where";
						
			
			
			
			
			
			//-------------------------------------------------------------
			
			
			
			if($debug){
				//test
				echo "
				<!-- 
					QUERY -----------------------------------------
					$query
					-----------------------------------------
				-->";
				exit;
			}
			
		

			//ejecuto el query
			$result=$this->query($query, $count, $test);
			
			
			
			//devuelvo el array con el resultado de la b�squeda
			return $result;
			
		}
				
		//---------------------------------------------------------------------
		
		/**
		* @return Date (MySQL Formatted Date)
		* @param Date $date, dd/mm/aaaa
		* @desc 
			Convierto una fecha con el formato dd/mm/aaa
			al formato usado por MySQL: aaaa-mm-dd
		*/
		public function get_mysql_date($date){
			//genero un array con las partes de la fecha
			$date_array=explode("/", $date);

			$day=$date_array[0];
			$month=$date_array[1];
			$year=$date_array[2];
			
			//output MySQL Formatted date
			return "$year-$month-$day";
		}
		
		//---------------------------------------------------------------------

        /**
         * Generates a complex result array indicating the result type, description
         * and returning a data array with all the contents relevant to the
         * specific result type.
         *
         * Common error types: ok, err.
         *
         * @param string $type
         * @param string $decription
         * @param array $data
         * @return array
         */
        private function composeResult($type, $description, $data=""){
            $result["type"]         = $type;
            $result["description"]  = $description;
            $result["data"]         = $data;

            return $result;
        }

        /**
         * Returns true if the passed argument is a composed result of type error.
         *
         * @author Alberto Miranda
         * @param anything $result
         * @return boolean
         */
        public function isError($result){
            if(is_array($result)){
                if(array_key_exists("type", $result)){
                    if($result["type"]=="err") return true;
                }
            }
            return false;
        }

} //end class db


?>
